process.env.NODE_ENV = 'production';
//koa服务端
const Koa = require('koa');
const Router = require('koa-router');
const db = require('./common/database');
const bodyParser = require('koa-bodyparser');
const session = require('koa-session');
const static = require('koa-static');
const path = require('path');
const uuid = require('uuid/v4');
const compress = require('koa-compress');
const app = new Koa();
const httpsConfig = require('./httpsConfig');
const ssl = require('koa-sslify').default;
app.use(ssl());
app.use(compress({ threshold: 2048 }));
const config = require('./db_config');
let keys = [];
for (let i = 0; i < 10; i++) {
  keys.push(uuid().replace(/\-/g, ''));
}
app.keys = keys;

const CONFIG = {
  key: 'sess',
  maxAge: 86400000,
  httpOnly: false,
  overwrite: true,
  signed: true,
  rolling: false,
  renew: false
};

app.use(session(CONFIG, app));
app.use(static(path.resolve(__dirname, './www')));

//跨域和传递数据库到ctx
app.use(async (ctx, next) => {
  ctx.set({
    Accept: ' application/json, text/plain, */*',
    'Access-Control-Allow-Credentials': true,
    'Access-Control-Allow-Origin': 'http://localhost:3000'
  });

  ctx.db = db;
  if (ctx.session.user_symbol) {
    let result = (await ctx.db.select('sess_table', 'username', {
      user_symbol: ctx.session.user_symbol
    }))[0];
    console.log(result, 33333);
    if (result) {
      ctx.request.username = result.username;
    }
  }
  await next();
});
app.use(async (ctx, next) => {
  let { path, res } = ctx;
  if (
    path.startsWith('/exchange/') ||
    path.startsWith('/markets/') ||
    path.startsWith('/asset')
  ) {
    ctx.redirect('/');
  }
  await next();
});
//解析post域
app.use(bodyParser());

//路由
let router = new Router();
// router.use('/home', require('./routers/getIndex.router'));
router.use('/login/', require('./routers/login.router'));
router.use('/register/', require('./routers/register.router'));
router.use('/api/', require('./routers/api.router'));
// router.use('/_next/', require('./routers/next.router'));

app.use(router.routes());
//为了websocket拆分出原生httpnextApp
let httpServer = require('http')
  .createServer((req, res) => {
    res.writeHead(301, { Location: 'https://47.107.78.122' });
    res.end();
  })
  .listen(80);
let server = require('https').createServer(httpsConfig, app.callback());
server.listen(config.SERVER_PORT, err => {
  if (err) {
    console.log(err);
  } else {
    console.log(`access by ${config.HOST}:${config.SERVER_PORT}`);
  }
});

//ws服务端
const io = require('socket.io')(server);
const { Client } = require('./common');
let socketClient = null;
io.of('/ws').on('connection', socket => {
  //爬虫
  if (
    !socketClient ||
    !socketClient.socket ||
    (socketClient.socket.readyState !== 1 &&
      socketClient.socket.readyState !== 0)
  ) {
    //这里必须加上socketClient.readyState === 2，因为是无数个用户并发的，所以可能正在关闭socket，此时socketclient还存在
    socketClient = new Client('wss://api.huobi.br.com/ws');
    socketClient.onerror();
    socketClient.onopen();
    socketClient.onclose();
    socketClient.onmessage();
    socketClient.reqQueue = [socket];
    console.log('新建socket');
  } else {
    //初始化每个心跳检测参数
    socket.check_times = 0;
    socket.pong_data = 'pong';
    socketClient.reqQueue.push(socket); //监听pang
  }
  socket.on('pang', data => {
    // console.log('客户端回应了我');
    socket.pong_data = data;
  });
  //收到socket订阅
  socket.on('sub', data => {
    let has = false;
    socketClient.all_socket_arr_sub.forEach(all_item => {
      if (all_item.sub === data.sub) {
        has = true;
      }
    });
    if (!has) {
      socketClient.all_socket_arr_sub.push(data);
      if (
        socketClient &&
        socketClient.socket &&
        socketClient.socket.readyState == 1
      ) {
        socketClient.socket.send(JSON.stringify(data));
      }
      console.log('向huobi请求新的' + data.sub + '订阅');
      console.log(socketClient.all_socket_arr_sub, 4444444444);
      console.log(socketClient.prev_all_socket_arr_sub, 3333);
    }

    //为socket添加一个它所有订阅的数组
    if (!socket.arr_sub) {
      socket.arr_sub = [];
      socket.arr_sub.push(data);
      console.log(`向${socket.id}添加订阅${data.sub}`);
    } else {
      let has = false;
      socket.arr_sub.forEach(item => {
        if (item.sub === data.sub) {
          has = true;
        }
      });
      if (!has) {
        console.log(`向${socket.id}添加订阅${data.sub}111`);
        socket.arr_sub.push(data);
      }
    }
  });

  socket.on('unsub', data => {
    if (socket.arr_sub) {
      socket.arr_sub = socket.arr_sub.filter(
        item => !(item.sub === data.unsub)
      );
    }
    // console.log('unsub', data.unsub);
    //如果取消的订阅，所有的socket都没有订阅，则向huobi取消它
    let has = false;
    socketClient.reqQueue.forEach(socket => {
      socket.arr_sub &&
        socket.arr_sub.forEach(sub_item => {
          if (sub_item.sub === data.unsub) {
            has = true;
          }
        });
    });
    // 过滤掉不需要向huobi请求的订阅，且向火币取消订阅
    if (!has) {
      if (socketClient.socket.readyState === 1) {
        socketClient.socket.send(JSON.stringify({ unsub: data.unsub }));
      }
      console.log(`向huobi取消订阅${data.unsub}`);
      socketClient.all_socket_arr_sub = socketClient.all_socket_arr_sub.filter(
        item => !(item.sub === data.unsub)
      );
      // console.log(socketClient.all_socket_arr_sub, '3333333333333');
    }

    // socketClient.arr_sub = socketClient.arr_sub.filter(my_sub => {
    //   let has = false;
    //   socket_sub => {
    //     if (socket_sub.sub === my_sub.sub) {
    //       has = true;
    //     }
    //   };
    //   if (!has) {
    //     console.log('向huobi取消' + my_sub + '的订阅111111111111111111');
    //   }
    //   return !has;
    // });
  });
  console.log(
    `用户:${socket.id}连接成功   目前在线人数:${socketClient.reqQueue.length}人`
  );
  socket.req_arr = [];
  socket.on('req', data => {
    socket.req_arr.push(data);
    console.log(data, 444444444444444444);
    console.log('收到req', 324234234234);
    if (
      socketClient &&
      socketClient.socket &&
      socketClient.socket.readyState == 1
    ) {
      socketClient.socket.send(JSON.stringify(data));
    } else {
      socketClient.initial_req_arr.push(data);
    }
  });
});
